home *** CD-ROM | disk | FTP | other *** search
/ Light ROM 3 / Light ROM 3 - Disc 2.iso / programs / pc / vp2raw / vp2raw.c next >
C/C++ Source or Header  |  1993-01-12  |  19KB  |  647 lines

  1. /***************************************************************************/
  2. /*                                                                         */
  3. /*    VP2RAW.C  Viewpoint to Raw triangle converter                        */
  4. /*                                                                         */
  5. /*            Takes the 3 numbers following the delimiter v, stores        */
  6. /*            them in an array, then reads the connection table and        */
  7. /*            generates a polygon data file that's converted into          */   
  8. /*            triangles                                                    */
  9. /*                                                                         */
  10. /*            Written to get Viewpoint files into anything else.           */
  11. /*                                                                         */
  12. /*    Jeff Bowermaster & Steve Anger                                       */
  13. /*           Splat! Graphics                                               */
  14. /*               1/11/93                                                   */
  15. /*                                                                         */
  16. /*    Syntax:  VP2RAW filename.ext [outfile]                               */
  17. /*                                                                         */
  18. /*    Input: A Viewpoint object file                                       */
  19. /*                                                                         */
  20. /*       g                                                                 */
  21. /*       v 3.660927 0.002173 -0.738231                                     */
  22. /*       v 3.719482 0.346536 -0.832918                                     */
  23. /*       v ...                                                             */
  24. /*                                                                         */
  25. /*    Output:  filename.RAW (or a specified filename)                      */
  26. /*                                                                         */
  27. /*       in the form:                                                      */
  28. /*                                                                         */
  29. /*    texture                                                              */
  30. /*    vx1 vy1 vz1 vx2 vy2 vz2 vx3 vy3 vz3                                  */
  31. /*    vx1 vy1 vz1 vx2 vy2 vz2 vx3 vy3 vz3                                  */
  32. /*    vx1 vy1 vz1 vx2 vy2 vz2 vx3 vy3 vz3                                  */
  33. /*    vx1 vy1 vz1 vx2 vy2 vz2 vx3 vy3 vz3                                  */
  34. /*    ...                                                                  */
  35. /*                                                                         */
  36. /*    Some cluze:                                                          */
  37. /*                                                                         */
  38. /*    vn 0.332949 -0.705421 0.625720                                       */
  39. /*    vn -0.260047 -0.789584 0.555817                                      */
  40. /*    vn 0.532304 -0.547688 0.645515                                       */
  41. /*    vn -0.440163 0.835449 -0.329062                                      */
  42. /*                                                                         */
  43. /* vn Viewpoint files can contain vn (vertex normal) information, and      */
  44. /*    based on the fact that there are usually more vertex normals than    */
  45. /*    vertex's (vertii?) I assume they are normal to the center of the     */
  46. /*    polygon, but I get really vague about the reason. I don't use them.  */
  47. /*                                                                         */
  48. /*    Folowing the vn's, there is a connection table in the form:          */
  49. /*                                                                         */
  50. /*    g coat                                                               */
  51. /*    s 1                                                                  */
  52. /*    f 66//52 67//53 68//54 69//55                                        */
  53. /*    f 69//55 68//54 70//56 71//57                                        */
  54. /*    f 71//57 70//56 72//58 73//59                                        */
  55. /*    f 73//59 72//58 74//60 75//61                                        */
  56. /*    f 75//61 74//60 76//62 77//63                                        */
  57. /*    f 77//63 76//62 78//64 79//65                                        */
  58. /*    f 79//65 78//64 80//66 81//67                                        */
  59. /*    ...                                                                  */
  60. /*                                                                         */
  61. /* g  I parse the name (coat) and define a texture block with the color    */
  62. /*    gray.  Go in and edit these textures to whatever you like.           */
  63. /*                                                                         */
  64. /* s  May be a smoothing group.  I just ignore it too.                     */
  65. /*                                                                         */
  66. /* f  The first number (before the //) is the vertex, the second number    */
  67. /*    is the normal.  Lines denote individual polygons, thus these are     */
  68. /*    all squares.  I've seen 13gons (tridecagons), but they are generally */
  69. /*    3-4-5 gons.                                                          */
  70. /*                                                                         */
  71. /*    Some Viewpoint files do not contain vertex normals so the connection */
  72. /*    table can be used directly.  I'm also leaving that one up to you.    */
  73. /*                                                                         */
  74. /*    Thank you Viewpoint for allowing these files to be distributed so    */
  75. /*    freely.  Awfully decent of you people.                               */
  76. /*                                                                         */
  77. /***************************************************************************/
  78.  
  79. #include <math.h>
  80. #include <string.h>
  81. #include <alloc.h>
  82. #include <stdio.h>
  83. #include <stdlib.h>
  84.  
  85. typedef struct
  86. {
  87.      float x, y, z;
  88. }
  89. Vector;
  90.  
  91. int remove_triangle (Vector *poly, int *polysize, Vector *v1, Vector *v2,
  92.      Vector *v3);
  93. int poly_inside (Vector *poly, int polysize, Vector *v);
  94. void vect_init (Vector *v, float x, float y, float z);
  95. void vect_copy (Vector *v1, Vector *v2);
  96. void vect_add (Vector *v1, Vector *v2, Vector *v3);
  97. void vect_sub (Vector *v1, Vector *v2, Vector *v3);
  98. void vect_scale (Vector *v, float k);
  99. float vect_mag (Vector *v);
  100. float dot_prod (Vector *v1, Vector *v2);
  101. void cross_prod (Vector *v1, Vector *v2, Vector *v3);
  102. float vect_angle (Vector *v1, Vector *v2);
  103. void add_ext (char *fname, char *ext, int force);
  104. int polyread (int argc, char *argv[]);
  105.  
  106.  
  107. void main(int argc, char *argv[])
  108. {
  109.     char *ptr, *infile, *outfile, *string, buffer[5];
  110.     char parse0, parse1,*texture,tex[50][20];
  111.     FILE *in, *out;
  112.     int a,count,i,n,t,textures,x,done,length,pos,point1,point2,vertexnum[15],have;
  113.     Vector vertex;
  114.     Vector huge *coords = NULL;
  115.     Vector huge *keep;
  116.  
  117.  
  118.     printf("(V)iew(P)oint 2 (RAW) Triangle Translator\n");
  119.     printf(" (c) 1993 Jeff Bowermaster & Steve Anger,\n     Splat! Graphics\n");
  120.  
  121.     if (argc < 2)
  122.     {
  123.         printf("\nUsage:  VP2RAW filename[.obj] [outfile]\n");
  124.         printf("          outfile defaults to filename.raw\n");
  125.         exit(1);
  126.     }
  127.  
  128.     string=(char *)malloc(256);
  129.     texture=(char *)malloc(80);
  130.  
  131.     infile=(char *)calloc(80,sizeof(char));
  132.     outfile=(char *)calloc(80,sizeof(char));
  133.  
  134.     strcpy (infile, argv[1]);
  135.  
  136.     if (argc > 2)
  137.        strcpy (outfile, argv[2]);
  138.     else {
  139.        strcpy (outfile, infile);
  140.        add_ext (outfile, "pol", 1);
  141.     }
  142.  
  143.     add_ext (infile, "obj", 1);
  144.    add_ext (outfile, "pol", 0);
  145.  
  146.     if ((in = fopen (infile, "r")) == NULL) {
  147.         printf ("Cannot open input file %s!\n", infile);
  148.         exit (1);
  149.     }
  150.  
  151.     if((out = fopen(outfile,"wt"))==NULL) {
  152.         printf ("Cannot open output file %s!\n", outfile);
  153.         exit (1);
  154.     }
  155.  
  156.     printf("\nReading %s for vertex count...\n",argv[1]);
  157.     count=0;
  158.     n=0;
  159.     while (fgets(string,256,in) != NULL) {      // get a line
  160.         parse0 = string[0];
  161.         parse1 = string[1];
  162.         switch (parse0) {
  163.             case 'v':
  164.             // v 3.660927 0.002173 -0.738231
  165.                 if(parse1==' ') {
  166.                     count++;
  167.                 }
  168.                 break;
  169.  
  170.             case 'g':
  171.             /* g skin */
  172.                 if(parse1==' ') {
  173.                     sscanf(string,"%*s %s",texture);
  174.                     have=0;
  175.                     for(x=0;x<n;x++)
  176.                         if(!strcmp(texture,tex[x])) have=1;
  177.                     if(!have)
  178.                         strcpy(tex[n++],texture);
  179.                 }
  180.                 break;
  181.  
  182.             default:   /*   Blank lines, page numbers...  */
  183.                 break;
  184.         }
  185.     }
  186.  
  187.     for(x=0;x<n;x++) {
  188.         for(a=0;a<strlen(tex[x]);a++) {
  189.             if(tex[x][a]==' ') tex[x][a] = '_';
  190.         }
  191.     printf(" %d %s\n",x,tex[x]);
  192.     }
  193.  
  194.     if ((coords = farmalloc ((long)count * sizeof(Vector)))==NULL) {
  195.         printf("Insufficient memory for vertices.\n");
  196.         exit(1);
  197.     }
  198.     else
  199.         printf("Allocating memory for %d vertices.\n",count);
  200.  
  201.     keep=coords;
  202.     printf("Writing data to %s.  Please wait...\n",outfile);
  203.  
  204.     textures=n;
  205.  
  206.     for(t=0;t<textures;t++) {
  207.         printf("Working on %s\n",tex[t]);
  208.         fprintf(out,"%s\n",tex[t]);
  209.         rewind(in);
  210.  
  211.         while (fgets(string,256,in) != NULL) {      // get a line
  212.             parse0 = string[0];
  213.             parse1 = string[1];
  214.             switch (parse0) {
  215.                 case 'v':
  216.                 // v 3.660927 0.002173 -0.738231
  217.                     if(parse1==' ' && !t) {
  218.                         sscanf(string,"%*s %f %f %f\n",
  219.                             &vertex.x,&vertex.y,&vertex.z);
  220.                         coords->x=vertex.x;
  221.                         coords->y=vertex.y;
  222.                         coords->z=vertex.z;
  223.                         coords++;
  224.                     //   fprintf(out,"%f %f %f\n",vertex.x,vertex.y,vertex.z);
  225.                     }
  226.                     break;
  227.  
  228.                 case 'g':
  229.                 /* g skin */
  230.                     sscanf(string,"%*s %s\n",texture);
  231.                     if(strcmp(tex[t],texture))
  232.                         break;
  233.                     break;
  234.  
  235.                 case 'f':
  236.                 /* f 2576//2175 2732//2331 2721//2320
  237.  
  238.                     1) get the numbers before the //
  239.                     2) save the first one
  240.                     3) repeat it at the end of the line
  241.  
  242.                 */
  243.                     if(strcmp(tex[t],texture))
  244.                         break;
  245.  
  246.                     coords=keep;
  247.                     length=strlen(string);
  248.  
  249.                     buffer[0]='\0';
  250.                     buffer[1]='\0';
  251.                     buffer[2]='\0';
  252.                     buffer[3]='\0';
  253.                     buffer[4]='\0';
  254.  
  255.                     pos = 0;
  256.                     n = 0;
  257.  
  258.                     for(x=2;x<length;x++){
  259.                         switch (string[x]) {
  260.  
  261.                             case '/':
  262.                               vertexnum[n++]=atoi(buffer);
  263.                               buffer[0]='\0';
  264.                               buffer[1]='\0';
  265.                               buffer[2]='\0';
  266.                               buffer[3]='\0';
  267.                               buffer[4]='\0';
  268.                               pos=0;
  269.                               while(string[x++]!=' ');
  270.                               x--;
  271.                             break;
  272.  
  273.                             case '0':
  274.                             case '1':
  275.                             case '2':
  276.                             case '3':
  277.                             case '4':
  278.                             case '5':
  279.                             case '6':
  280.                             case '7':
  281.                             case '8':
  282.                             case '9':
  283.                                 buffer[pos++]=string[x];
  284.                             break;
  285.  
  286.                             default:
  287.                                  break;
  288.                         }
  289.                     }
  290.  
  291.                     fprintf(out,"%d ",n);
  292.  
  293.                     for(i=0;i<n;i++)
  294.                         fprintf(out,"%f %f %f ",
  295.                             (coords+vertexnum[i]-1)->x,
  296.                             (coords+vertexnum[i]-1)->y,
  297.                             (coords+vertexnum[i]-1)->z);
  298.                     fprintf(out,"\n");
  299.  
  300.                     break;
  301.  
  302.                 default:   /*   Blank lines, page numbers...  */
  303.                     break;
  304.                 }
  305.             }
  306.         }
  307.         fclose(in);
  308.         fclose(out);
  309.  
  310.         polyread(argc,argv);
  311.     }
  312.  
  313. /*----------------------------------------------------------------------
  314.  
  315.         Polygon to triangle converter
  316.             by Steve Anger Jan 1993
  317.  
  318. This program is commited to the public domain. Feel free to use all or part
  319. of this code in your own programs.
  320.  
  321.  
  322. This is a utility that breaks polygon shapes down into individual
  323. triangles. The polygons are assumed to be planar however the program
  324. should be able to tolerate slightly non-planar shapes.
  325.  
  326. The input file consists of one line per polygon in the following format:
  327.  
  328.     n x1 y1 z1 x2 y2 z2 ..... xn yn zn
  329.  
  330. where n is the number of vertices in the polygon and xi, yi, and zi are the
  331. coordinates of the polygon's vertices.
  332.  
  333.  
  334. The output file consists of one triangle per line in the following format:
  335.  
  336.     x1 y1 z1 x2 y2 z2 x3 y3 z3
  337.  
  338.  
  339. -----------------------------------------------------------------------*/
  340.  
  341.  
  342. #define POLYMAX 17 
  343. #define BUFSIZ 512
  344.  
  345. int polyread (int argc, char *argv[])
  346. {
  347.     FILE   *f, *g;
  348.     Vector poly[POLYMAX], v1, v2, v3;
  349.     int    polysize, cnt, i, j, start;
  350.     char   infile[80] = "", outfile[80] = "",parse,*string,texture[20];
  351.  
  352.     if (argc < 2) {
  353.     printf ("Usage: infile[.pol] [outfile[.raw]]\n");
  354.     exit(1);
  355.     }
  356.     string=malloc(BUFSIZ);
  357.  
  358.     strcpy (infile, argv[1]);
  359.  
  360.     if (argc > 2)
  361.     strcpy (outfile, argv[2]);
  362.     else {
  363.     strcpy (outfile, infile);
  364.     add_ext (outfile, "raw", 1);
  365.     }
  366.  
  367.     add_ext (infile, "pol", 1);
  368.     add_ext (outfile, "raw", 0);
  369.  
  370.     f = fopen (infile, "r");
  371.     if (f == NULL) {
  372.     printf ("Unable to open input file '%s'\n", infile);
  373.     exit(1);
  374.     }
  375.  
  376.     g = fopen (outfile, "w");
  377.     if (g == NULL) {
  378.     printf ("Unable to open output file '%s'\n", outfile);
  379.     exit(1);
  380.     }
  381.  
  382.     printf("Converting polygons to triangles...\n");
  383.     cnt = 0;
  384.  
  385.     while (fgets(string,BUFSIZ,f) != NULL) {      // get a line
  386.         parse = string[0];
  387.  
  388.         switch (parse) {
  389.  
  390.             case '\x0A':
  391.                 break;
  392.  
  393.             case '0':
  394.             case '1':
  395.             case '2':
  396.             case '3':
  397.             case '4':
  398.             case '5':
  399.             case '6':
  400.             case '7':
  401.             case '8':
  402.             case '9':
  403.                 polysize = 0;
  404.                 start=1;
  405.  
  406.                 sscanf (string, "%d", &polysize);
  407.  
  408.                 if (polysize > POLYMAX) {
  409.                     printf ("Polygon %d too large (%d), skipping.\n",cnt,polysize);
  410.                     fgets(string,BUFSIZ,f);  //read to the end of this one
  411.                     break;
  412.                 }
  413.                 if(polysize>9)
  414.                     start=2;
  415.  
  416.                 for (i=0;i<polysize; i++) {
  417.                     sscanf (&string[start], "%f %f %f", &poly[i].x, &poly[i].y, &poly[i].z);
  418.                     for(j=0;j<3;j++){
  419.                       start=strchr(&string[start+1],' ')-string;
  420.                }
  421.                 }
  422.          
  423.              /* Remove triangles from the polygon until there's nothing left */
  424.              while (remove_triangle (poly, &polysize, &v1, &v2, &v3)) {
  425.                 fprintf (g, "%f %f %f %f %f %f %f %f %f \n",
  426.                      v1.x, v1.y, v1.z, v2.x, v2.y, v2.z, v3.x, v3.y, v3.z);
  427.              }
  428.          
  429.                 cnt++;
  430.          
  431.              if (cnt % 10 == 0)
  432.                 printf ("%d\r", cnt);
  433.             break;
  434.  
  435.          default:
  436.             sscanf(string,"%s",&texture);
  437.             fprintf(g,"%s\n",texture);
  438.             break;
  439.         }
  440.  
  441.     }
  442.  
  443.    fclose (f);
  444.    fclose (g);
  445.  
  446.    return (0);
  447. }
  448.  
  449.  
  450. /* Removes a triangle from the specified polygon. */
  451. /* The size of the polygon is reduced */
  452. int remove_triangle (Vector *poly, int *polysize,Vector *v1, Vector *v2, Vector *v3)
  453. {
  454.    Vector tri[3], center;
  455.    int   i, j, a, b, c;
  456.  
  457.    if (*polysize < 3)
  458.     return 0; /* No triangle found */
  459.  
  460.    /* This simplest case */
  461.    if (*polysize == 3) {
  462.       vect_copy (v1, &poly[0]);
  463.        vect_copy (v2, &poly[1]);
  464.        vect_copy (v3, &poly[2]);
  465.  
  466.        *polysize = 0;
  467.  
  468.        return 1;  /* Ok */
  469.    }
  470.  
  471.    for (i = 0; i < *polysize; i++) {
  472.        a = i;
  473.        b = (i + 1) % *polysize;
  474.        c = (i + 2) % *polysize;
  475.  
  476.     /* Select a candidate triangle */
  477.        vect_copy (&tri[0], &poly[a]);
  478.        vect_copy (&tri[1], &poly[b]);
  479.        vect_copy (&tri[2], &poly[c]);
  480.  
  481.     /* Calculate the center of the triangle */
  482.        vect_init (¢er, 0.0, 0.0, 0.0);
  483.        vect_add (¢er, ¢er, &tri[0]);
  484.        vect_add (¢er, ¢er, &tri[1]);
  485.        vect_add (¢er, ¢er, &tri[2]);
  486.        vect_scale (¢er, 1.0/3.0);
  487.  
  488.     /* Is the center of the triangle inside the original polygon? */
  489.     /* If not skip this triangle */
  490.        if (!poly_inside (poly, *polysize, ¢er))
  491.           continue;
  492.  
  493.     /* Are any of the polygons other vertices inside the triangle */
  494.     /* If so skip this triangle */
  495.        for (j = 0; j < *polysize; j++) {
  496.           if (j != a && j != b && j != c && poly_inside (tri, 3, &poly[j]))
  497.            break;
  498.        }
  499.  
  500.        if (j < *polysize)
  501.           continue;
  502.  
  503.     /* This is the one */
  504.        vect_copy (v1, &tri[0]);
  505.        vect_copy (v2, &tri[1]);
  506.        vect_copy (v3, &tri[2]);
  507.  
  508.     /* Remove this triangle from the polygon */
  509.        (*polysize)--;
  510.        for (j = b; j < *polysize; j++)
  511.           vect_copy (&poly[j], &poly[j+1]);
  512.  
  513.        return 1; /* Ok */
  514.    }
  515.    return 0; /* No triangle found */
  516. }
  517.  
  518.  
  519. /* Determines if the specified point 'v' is inside the polygon. */
  520. /* Uses a convoluted version of the sum of angles approach */
  521. int poly_inside (Vector *poly, int polysize, Vector *v)
  522. {
  523.    Vector sum, cross, v1, v2;
  524.    float  magcross;
  525.    int   i;
  526.  
  527.    vect_init (&sum, 0.0, 0.0, 0.0);
  528.  
  529.    for (i = 0; i < polysize; i++) {
  530.        vect_sub (&v1, v, &poly[i]);
  531.        vect_sub (&v2, v, &poly[(i+1) % polysize]);
  532.  
  533.        cross_prod (&cross, &v1, &v2);
  534.        magcross = vect_mag (&cross);
  535.  
  536.        if (magcross > 0.0)
  537.           vect_scale (&cross, 1.0/magcross);
  538.  
  539.        vect_scale (&cross, vect_angle (&v1, &v2));
  540.        vect_add (&sum, &sum, &cross);
  541.    }
  542.    return (vect_mag (&sum) > M_PI);
  543. }
  544.  
  545.  
  546. void vect_init (Vector *v, float  x, float  y, float  z)
  547. {
  548.    v->x = x;
  549.    v->y = y;
  550.    v->z = z;
  551. }
  552.  
  553.  
  554. void vect_copy (Vector *v1, Vector *v2)
  555. {
  556.    v1->x = v2->x;
  557.    v1->y = v2->y;
  558.    v1->z = v2->z;
  559. }
  560.  
  561.  
  562. void vect_add (Vector *v1, Vector *v2, Vector *v3)
  563. {
  564.    v1->x = v2->x + v3->x;
  565.    v1->y = v2->y + v3->y;
  566.    v1->z = v2->z + v3->z;
  567. }
  568.  
  569.  
  570. void vect_sub (Vector *v1, Vector *v2, Vector *v3)
  571. {
  572.    v1->x = v2->x - v3->x;
  573.    v1->y = v2->y - v3->y;
  574.    v1->z = v2->z - v3->z;
  575. }
  576.  
  577.  
  578. void vect_scale (Vector *v, float  k)
  579. {
  580.    v->x = k * v->x;
  581.    v->y = k * v->y;
  582.    v->z = k * v->z;
  583. }
  584.  
  585.  
  586. float vect_mag (Vector *v)
  587. {
  588.    float  mag = sqrt(v->x*v->x + v->y*v->y + v->z*v->z);
  589.  
  590.    return mag;
  591. }
  592.  
  593.  
  594. float dot_prod (Vector *v1, Vector *v2)
  595. {
  596.    return (v1->x*v2->x + v1->y*v2->y + v1->z*v2->z);
  597. }
  598.  
  599.  
  600. void cross_prod (Vector *v1, Vector *v2, Vector *v3)
  601. {
  602.    v1->x = (v2->y * v3->z) - (v2->z * v3->y);
  603.    v1->y = (v2->z * v3->x) - (v2->x * v3->z);
  604.    v1->z = (v2->x * v3->y) - (v2->y * v3->x);
  605. }
  606.  
  607.  
  608. /* Return the angle (rads) between two vectors */
  609. float vect_angle (Vector *v1, Vector *v2)
  610. {
  611.    float  mag1, mag2, angle, cos_theta;
  612.  
  613.    mag1 = vect_mag(v1);
  614.    mag2 = vect_mag(v2);
  615.  
  616.    if (mag1 * mag2 == 0.0)
  617.     angle = 0.0;
  618.    else {
  619.     cos_theta = dot_prod(v1,v2) / (mag1 * mag2);
  620.  
  621.     if (cos_theta <= -1.0)
  622.        angle = M_PI;
  623.     else if (cos_theta >= +1.0)
  624.        angle = 0.0;
  625.     else
  626.        angle = acos(cos_theta);
  627.    }
  628.  
  629.    return angle;
  630. }
  631.  
  632.  
  633. void add_ext (char *fname, char *ext, int force)
  634. {
  635.    int i;
  636.  
  637.    for (i = 0; i < strlen(fname); i++)
  638.     if (fname[i] == '.') break;
  639.  
  640.    if (fname[i] == '\0' || force) {
  641.     if (strlen(ext) > 0)
  642.        fname[i++] = '.';
  643.  
  644.     strcpy (&fname[i], ext);
  645.    }
  646. }
  647.